<?php

namespace app\api\model;

use Exception;
use think\Cache;
use think\Db;
use think\Model;

class BaseModel extends Model
{
    private static $errorMsg;

    const DEFAULT_ERROR_MSG = '操作失败,请稍候再试!';
    protected static $tableName = '';

    /**
     * 设置错误信息
     * @param string $errorMsg
     * @return bool
     */
    protected static function setErrorInfo($errorMsg = self::DEFAULT_ERROR_MSG, $rollback = false)
    {
        if ($rollback) self::rollbackTrans();
        self::$errorMsg = $errorMsg;
        return false;
    }

    /**
     * 获取错误信息
     * @param string $defaultMsg
     * @return string
     */
    public static function getErrorInfo($defaultMsg = self::DEFAULT_ERROR_MSG)
    {
        return !empty(self::$errorMsg) ? self::$errorMsg : $defaultMsg;
    }

    /**
     * 开启事务
     */
    public static function beginTrans()
    {
        Db::startTrans();
    }

    /**
     * 提交事务
     */
    public static function commitTrans()
    {
        Db::commit();
    }

    /**
     * 关闭事务
     */
    public static function rollbackTrans()
    {
        Db::rollback();
    }

    /**
     * 根据结果提交滚回事务
     * @param $res
     */
    public static function checkTrans($res)
    {
        if ($res) {
            self::commitTrans();
        } else {
            self::rollbackTrans();
        }
    }

    public static function isRun($key, $second = 60, $return = false)
    {
        if (Cache::has($key)) {
            if ($return) {
                return false;
            } else {
                exit;
            }
        } else {
            Cache::set($key, 1, $second);
        }
        if ($return) {
            return true;
        }
    }

    public static function removeRun($key, $num = 3)
    {
        if ($num > 0) {
            try {
                Cache::rm($key);
            } catch (Exception $e) {
                self::removeRun($key, --$num);
            }
        }
    }

    /**
     * 日志记录
     * @param $file
     * @param $msg
     * @return bool
     */
    public static function log($file, $msg)
    {
        $dir = getcwd() . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR;
        if (!is_dir($dir)) {
            if (!mkdir($dir) && !is_dir($dir)) {
                return false;
            }
        }
        $time = date('Y-m-d', time());
        $log = $dir . "/{$file}{$time}.log";
        $strTime = date('m-d H:i:s', time());
        $msg = "[$strTime]$msg\r\n";
        if (!$fp = @fopen($log, "a")) {
            return false;
        }
        if (!fwrite($fp, $msg)) {
            return false;
        }
    }

    /**
     * 计算base64图片的大小
     * @param $base64_img
     * @return float|int
     */
    public static function size($base64_img)
    {
        $base64 = explode(',', $base64_img);
        $base64 = $base64[1];
        $base64 = str_replace('=', '', $base64);
        $img_len = strlen($base64);
        $file_size = $img_len - ($img_len / 8) * 2;
        return $file_size;
    }

    //获取数据列表
    public static function getList(array $where, $page = 1, $limit = 10, $field = '*', $order = 'id desc')
    {
        return self::where($where)->order($order)->field($field)->page((int)$page, (int)$limit)->select();
    }

    //查找所有数据
    public static function selectAll(array $where = [], $fields = '*', $orderBy = 'id asc')
    {
        $result = self::where($where)->field($fields)->order($orderBy)->select();
        return $result;
    }

    /**
     * 循环处理数组各个时间段，返回数组
     * @param  $modelArr ;要处理的数组
     * @param $numArr ;起始各个时间段数量的数组
     * @param $timeArr ;各个时间段的时间数组
     * @param $dateFormt ;要比较的时间格式字符串 如Y-m-d H 或者Y-m-d
     * @param $flag ;add_time是否要转换成int格式
     * @return array
     */
    public static function foreachArr($modelArr, $numArr, $timeArr, $dateFormt, $flag = true)
    {
        //各个时间段的数量
        foreach ($modelArr as $key => $value) {
            foreach ($timeArr as $k => $v) {
                $add_time = $flag ? strtotime($value['add_time']) : $value['add_time'];
                if (date($dateFormt, $add_time) == $v) {
                    $numArr[$k] += 1;
                }
            }
        }
        $data = [
            'dateAry' => $timeArr,
            'numAry' => $numArr,
        ];
        return $data;
    }

    //保存图片，返回图片的相对路径
    public static function saveImg($base64Img, $ext)
    {
        $documentRoot = ROOT_PATH . 'public';
        $relativePath = '/uploads/' . date("Ymd", time());
        $fullPath = $documentRoot . $relativePath;
        if (!is_dir($fullPath)) {       //判断目录是否存在 不存在就创建 并赋予777权限
            mkdir($fullPath, 0777, true);
        }
        $md5 = md5($base64Img);
        $rand = $md5 . rand(111, 999) . '.' . $ext;
        $relativePath .= '/' . $md5 . $rand;
        $imagePath = $fullPath . '/' . $md5 . $rand;
        try {
            file_put_contents($imagePath, base64_decode($base64Img));
            return $relativePath;
        } catch (\Exception $e) {
            return UserModel::setErrorInfo($e->getMessage());
        }
    }

    public static function scanMd5($uid)
    {
//        return md5($uid . 'scannacs');
        return crypt($uid, 'scannacs');
    }

    public static function accessTokenKey()
    {
        return 'jsk_wx_access_token';
    }

    public static function siteUrl()
    {
        return 'https://' . $_SERVER['HTTP_HOST'];
    }

    /**
     *求两个已知经纬度之间的距离,单位为千米
     * @param lng1,lng2 经度
     * @param lat1,lat2 纬度
     * @return float 距离，单位千米
     **/
    public static function distance($lng1, $lat1, $lng2, $lat2)//根据经纬度计算距离
    {
        //将角度转为弧度
        $radLat1 = deg2rad((float)$lat1);
        $radLat2 = deg2rad((float)$lat2);
        $radLng1 = deg2rad((float)$lng1);
        $radLng2 = deg2rad((float)$lng2);
        $a = $radLat1 - $radLat2;//两纬度之差,纬度<90
        $b = $radLng1 - $radLng2;//两经度之差纬度<180
        $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6378.137;
        return $s;
    }
}